gusucode.com > 支持向量机工具箱 - LIBSVM OSU_SVM LS_SVM源码程序 > 支持向量机工具箱 - LIBSVM OSU_SVM LS_SVM\stprtool\quadrat\quademo.m

    function result = quademo(action,hfigure,varargin)
% QUADEMO demo on non-linear (quadratic) data mapping.
%
% QUADEMO demonstrates use of the linear algorithms 
%  which find quadratic decision function using non-linear
%  data mapping. The original space (2D in this case) 
%  is mapped to the new one where the quadratic function
%  appears as the hyperplane. Following algorithms for
%  linear dicision rule synthesis can be used:
%
%  Perceptron  - Perceptron learning rule.
%  Kozinec     - Kozinec's algorithm.
%  e-Kozinec   - Modified Kozinec's algorithm finding e-optimal solution.
%  LinearSVM   - linear version of the Supprot Vector Machines.
%
% Control:
%  Algorithm  - select algorithm for testing.
%  Epsilon    - input parameter for the EKOZINEC algorithm 
%               (see help ekozinec).
%  Iterations - number of iterations in one step.
%  Animation  - enable/dissable animation.
%
%  FIG2EPS     - export screen to the PostScript file.
%  Load data   - load input point sets from file.
%  Create data - invoke program for creating point sets.
%  Reset       - set the tested algorithm to the initial state.
%  Play        - run the tested algorithm.
%  Stop        - stop the running algorithm.
%  Step        - perform only one step.
%  Info        - invoke the info box.
%  Close       - close the program.
%
% See also QTRANSF, L2Q2D, QUAD2D, PQUAD2D, 
%   PERCEPTR, KOZINEC, EKOZINEC, LINSVM.
%

% Statistical Pattern Recognition Toolbox, Vojtech Franc, Vaclav Hlavac
% (c) Czech Technical University Prague, http://cmp.felk.cvut.cz
% Written Vojtech Franc (diploma thesis) 19.11.1999, 23.12.1999, 27.02.2000
% Modifications
% 26-June-2001, V.Franc, comments repared.
% 24. 6.00 V. Hlavac, comments polished.
% 16-dec-2000, new comments, used linsvm function instead of svm

LINE_WIDTH=1;          % width of separation line
ANIM_STEPS=10;         % number of steps during line animation
BORDER=.4;             % minimal space between axis and every point in
DATA_IDENT='Finite sets, Enumeration';   % file identifier

% if number of arguments is less then 1, that means first call of this function. Every
% other calls set up at least argument action
if nargin < 1,
   action = 'initialize';
end

% what action is required ?
switch lower(action)

case 'initialize'
   % == Initialize user interface control and figure window ================

   % == Figure =============================================================
   left=0.1;
   width=0.8;
   bottom=0.1;
   height=0.8;
   hfigure=figure('Name','Quadratic discriminant function', ...
      'Visible','off',...
    'NumberTitle','off', ...
      'tag','Quademo',...
      'Units','normalized', ...
      'Position',[left bottom width height],...
       'Units','normalized', ...
      'RendererMode','manual');

   % == Axes ===============================================================
   left=0.1;
   width=0.65;
   bottom=0.35;
   height=0.60;
   haxes1=axes(...
       'Units','normalized', ...
      'Box','on', ...
      'DrawMode','fast',...
      'NextPlot','add',...
      'UserData',[],...
      'Position',[left bottom width height]);
   xlabel('feature x');
   ylabel('feature y');

   % == Comment window =====================================================

   % Comment Window frame
   bottom=0.05;
   height=0.2;
   uicontrol( ...
        'Style','frame', ...
        'Units','normalized', ...
        'Position',[left bottom width height], ...
        'BackgroundColor',[0.5 0.5 0.5]);

   % Text label
   uicontrol( ...
        'Style','text', ...
        'Units','normalized', ...
        'Position',[left height-0.01 width 0.05], ...
        'BackgroundColor',[0.5 0.5 0.5], ...
        'ForegroundColor',[1 1 1], ...
        'String','Comment Window');

   % Edit window
   border=0.01;
   hconsole=uicontrol( ...
        'Style','edit', ...
        'HorizontalAlignment','left', ...
        'Units','normalized', ...
        'Max',10, ...
        'BackgroundColor',[1 1 1], ...
        'Position',[left+border bottom width-2*border height-0.05], ...
        'Enable','inactive',...
        'String','');


    % == Buttons ===========================================================
   % -- Export to EPS ---------
   width=0.1;
   left=0.75-width;
   bottom=0.95;
   height=0.04;
   hbtclose = uicontrol(...
    'Units','Normalized', ...
      'Callback','fig2eps(gcf)',...
        'ListboxTop',0, ...
        'Position',[left bottom width height], ...
      'String','FIG2EPS');
   %----------------------------------

   % Close button
   left=0.8;
   bottom=0.05;
   height=0.05;
   width=0.15;
   hbtclose = uicontrol(...
    'Units','Normalized', ...
      'Callback','close(gcf)',...
        'ListboxTop',0, ...
        'Position',[left bottom width height], ...
        'String','Close');

   % Info button: call stanard info box
   bottom=bottom+1.5*height;
   hbtinfo = uicontrol(...
    'Units','Normalized', ...
      'Callback','quademo(''info'',gcf)',...
        'ListboxTop',0, ...
        'Position',[left bottom width height], ...
        'String','Info');

   % Step button: perform one adaptation step
   bottom=bottom+1.5*height;
    hbtstep = uicontrol(...
      'Units','Normalized', ...
      'ListboxTop',0, ...
        'Position',[left bottom width height], ...
      'String','Step', ...
      'Callback','quademo(''step'',gcf)');

   % Stop button: stop process of adaptation
   bottom=bottom+height;
   hbtstop = uicontrol(...
    'Units','Normalized', ...
        'ListboxTop',0, ...
        'Position',[left bottom width height], ...
      'String','Stop', ...
      'Callback','set(gcbo,''UserData'',1)',...
      'Enable','off');

   % Play button: start up adaptation
   bottom=bottom+height;
   hbtplay = uicontrol(...
    'Units','Normalized', ...
      'ListboxTop',0, ...
        'Position',[left bottom width height], ...
      'String','Play', ...
      'Callback','quademo(''play'',gcf)');

   % Reset button: set up t = 0
   bottom=bottom+height;
    hbtreset = uicontrol(...
      'Units','Normalized', ...
      'ListboxTop',0, ...
        'Position',[left bottom width height], ...
      'String','Reset', ...
      'Callback','quademo(''reset'',gcf)');

   % Create data
   bottom=bottom+1.5*height;
    hbtcreat = uicontrol(...
      'Units','Normalized', ...
      'ListboxTop',0, ...
        'Position',[left bottom width height], ...
      'String','Create data', ...
      'Callback','quademo(''creatdata'',gcf)');

   % Load data
   bottom=bottom+1*height;
    hbtload = uicontrol(...
      'Units','Normalized', ...
      'ListboxTop',0, ...
        'Position',[left bottom width height], ...
      'String','Load data', ...
      'Callback','quademo(''getfile'',gcf)');

   % == Popup menus ==========================================================

   % Pop up menu for the selection among algorithms
    % title
   bottom=0.95-height;
   htxalgo=uicontrol( ...
      'Style','text', ...
      'Units','normalized', ...
      'Position',[left bottom width height], ...
      'String','Algorithm');
   % popup menu
   bottom=bottom-height;
   hpualgo=uicontrol( ...
      'Style','popup', ...
      'Units','normalized', ...
      'CallBack','quademo(''epshandler'',gcf)',...
      'Position',[left bottom width height], ...
      'String',['Perceptron';'Kozinec   ';'e-Kozinec ';'LinearSVM ']);


   % == Edit line ==========================================================
   % epsilon
   bottom=bottom-1.2*height;
   htxeps=uicontrol( ...
      'Style','text', ...
      'Units','normalized', ...
      'Position',[left bottom width 0.9*height], ...
      'Enable','off',...
      'String','epsilon');
   bottom=bottom-height;
   hedeps = uicontrol(...
    'Units','normalized', ...
      'ListboxTop',0, ...
        'Position',[left bottom width height], ...
      'Style','edit',...
      'Enable','off',...
      'CallBack','quademo(''epshandler'',gcf)',...
      'String','1e-3');

   % # of iterations
   bottom=bottom-1.1*height;
   htxiter=uicontrol( ...
      'Style','text', ...
      'Units','normalized', ...
      'Position',[left bottom width 0.9*height], ...
      'String','Iterations');

   bottom=bottom-0.9*height;
   hediter = uicontrol(...
    'Units','normalized', ...
      'ListboxTop',0, ...
        'Position',[left bottom width height], ...
      'Style','edit',...
      'CallBack','quademo(''iterhandler'',gcf)',...
      'String','1');

   % == Check boxes ===============================================================

   % Make chack box to determine if a line will be drawn in one step or fluently.
   bottom=bottom-height*1.2;
    hxbanim = uicontrol(...
    'Style','checkbox', ...
    'Units','normalized', ...
    'ListboxTop',0, ...
    'Position',[left bottom width height], ...
    'String','Animation');


    % ==============================================================================

   % Store handlers
   handlers=struct(...
      'line',struct('handler1',-1,'handler2',-1,'alpha',0,'fi',0,'t',0),...
      'btstep',hbtstep,...
      'btstop',hbtstop,...
      'btclose',hbtclose,...
      'btplay',hbtplay,...
      'btreset',hbtreset,...
      'btinfo',hbtinfo,...
      'btload',hbtload,...
      'btcreat',hbtcreat,...
      'pualgo',hpualgo,...
      'console',hconsole,...
      'editer',hediter,...
      'edeps',hedeps,...
      'txeps',htxeps,...
      'axes1',haxes1,...
      'xbanim',hxbanim);

   set(hfigure,'UserData',handlers)

   % Reset
   quademo('reset',gcf);

   % Put figure on desktop
   set(hfigure,'Visible','on');
   drawnow;


case 'iterhandler'
   % == Handler for edit line Iterations ====================================
   h=get(hfigure,'UserData');

   iter=round(str2num(get(h.editer,'String')));
   if isempty(iter) | iter < 1, iter=1; end
   set(h.editer,'String',num2str(iter));

case 'epshandler'
   % == Handler for edit line Epsilon ======================================
   h=get(hfigure,'UserData');

   if get(h.pualgo,'Value')==3,
      % algorithm e-Kozinec is selected
      set(h.edeps,'Enable','on');
      set(h.txeps,'Enable','on');

      epsil=str2num(get(h.edeps,'String'));
      if epsil < 0,
         epsil=1;
         set(h.edeps,'String',num2str(epsil));
      end
   else
      set(h.edeps,'Enable','off');
      set(h.txeps,'Enable','off');
   end


case 'creatdata'
   % == Invoke data set creator ============================================
   creatset('finite',2,'quademo','created',hfigure);


case 'created'
   % == Load new created data set ===========================================

   % get handler and make this figure active
   figure(hfigure);
   h=get(hfigure,'UserData');

   % get file name
   path=varargin{1};
   name=varargin{2};
   pathname=strcat(path,name);

   if checkdat(pathname,DATA_IDENT,2,[0 0])==1,
      file.pathname=pathname;
      file.path=path;
      file.name=name;
      set(h.btload,'UserData',file);
      quademo('loadsets',hfigure);
      quademo('reset',hfigure);
   else
      errordlg('This file does not contain required data.','Bad file','modal');
   end


case 'getfile'
   % == Invoke standard open file dialog ====================================
   % Opens file and checks if contains appropriate data, if yes loads data.

   h=get(hfigure,'UserData');

   % change path to directory
%%   wres=what('quadrat');
%%   cd(wres.path);

   [name,path]=uigetfile('*.mat','Open file');
   if name~=0,
      file.pathname=strcat(path,name);
      file.path=path;
      file.name=name;
      if checkdat(file.pathname,DATA_IDENT,2,[0 0])==1,
         set(h.btload,'UserData',file);
         quademo('loadsets',hfigure);
         quademo('reset',hfigure);
      else
         errordlg('This file does not contain required data.','Bad file','modal');
      end
   end

case 'redraw'
   % == Redraw points in axes ======================================================

   h=get(hfigure,'UserData');                   % uicontrol handlers

   % get sets with points
   sets=get(h.axes1,'UserData');
   if isempty(sets)==1,
      return;
   end

   % clears axes
   set(get(h.axes1,'Children'),'EraseMode','normal');
   clrchild(h.axes1);
   h.line.handler1=plot(...
      'Parent',h.axes1,...
      [0],[0],'Visible','off','LineWidth',LINE_WIDTH,'EraseMode','xor','Color','k');
   h.line.handler2=plot(...
      'Parent',h.axes1,...
      [0],[0],'Visible','off','LineWidth',LINE_WIDTH,'EraseMode','xor','Color','k');
   set(hfigure,'UserData',h);                   % uicontrol handlers
   quademo('drawline',hfigure,h.line.fi,h.line.alpha);

   % Appear point in 2D plane.
%%   pplot(sets.X,sets.I);
   ppoints(sets.X,sets.I);
   drawnow;

case 'loadsets'
   % == Load sets ==================================================================
   % Get file name from the pop up menu according to menu pointer. Than clear axes,
   % load new file and appear the points from him.

   h=get(hfigure,'UserData');                   % uicontrol handlers

   % Clear axes
   %   cla reset;
   clrchild(h.axes1);
%      'XTick',[],'YTick',[], ...
   set(h.axes1, ...
      'Box','on', ...
      'NextPlot','add',...
      'DrawMode','fast' );
   xlabel('feature x');
   ylabel('feature y');

   % No line
   h.line.handler1=-1;
   h.line.handler2=-1;
   set(hfigure,'UserData',h);

   % Get file name with sets
   file=get(h.btload,'UserData');

   % Load sets
   sets=load(file.pathname);

   % store loaded sets
   set(h.axes1,'UserData',sets);

   % set axes according to current points
   win=cmpwin(min(sets.X'),max(sets.X'),BORDER,BORDER);
   setaxis(h.axes1,win);
%   axis(win);

   % Appear point in 2D plane.
   % points from set X1 and X2
%   K=sum(sets.K);
%   if K <= BIG_POINTS_NUM,
%      set(h.xbsize,'Value',1);
%      pointsize=BIG_POINT_SIZE;
%   else
%      set(h.xbsize,'Value',0);
%      pointsize=SMALL_POINT_SIZE;
%   end
%   pplot(sets.X,sets.I,pointsize);

%%%   pplot(sets.X,sets.I);
   ppoints(sets.X,sets.I);

case 'play'
   % == Start up the adaptation process =======================================
   % Perform the adaptation step by step until the solution is found or stop
   % button is pushed down.

   h=get(hfigure,'UserData');                      % get handlers

   % Get sets
   sets=get(h.axes1,'UserData');

   % no data set loaded
   if isempty(sets)==1,
      return;
   end

   % Disable buttons everything axcept
   set([h.btinfo h.btstep h.btclose h.btplay h.btreset h.btload h.btcreat h.pualgo ...
       h.editer],'Enable','off');

   % Only stop button can be pushed down
   set(h.btstop,'Enable','on');


   % Stop button was not pushed down
   set(h.btstop,'UserData',0);
   play=1;

   % get parameters
   t=h.line.t;
   alpha=h.line.alpha;
   fi=h.line.fi;
   X=qtransf(sets.X);

   % get # of iterations
   iter=max(1,round(str2num(get(h.editer,'String'))));

   % get epsilon
   epsil=str2num(get(h.edeps,'String'));

   % Play - adaptation process
   while play==1 & get(h.btstop,'UserData')==0,

       % perfor one adaptation step
      switch get(h.pualgo,'Value')
      case 1
         [alpha,fi,solution,tplus1]=perceptr(X,sets.I,iter,t,alpha,fi);
      case 2
         [alpha,fi,solution,tplus1]=kozinec(X,sets.I,iter,t,alpha,fi);
      case 3
         [alpha,fi,solution,tplus1]=ekozinec(X,sets.I,epsil,iter,t,alpha,fi);
      case 4
         [alpha,fi,solution]=linsvm(X,sets.I);
         if solution==0, solution=-1; end
         tplus1=1;
      end

      t=tplus1;

      if get(h.xbanim,'Value')==0,
         quademo('drawline',hfigure,fi,alpha);
      else
         quademo('animline',hfigure,fi,alpha);
      end

      if solution==0,
         % appear time and line parameters
         text=makeinfo(t,alpha,fi,solution);
      elseif solution==1,
         % print result
         text=makeinfo(t,alpha,fi,solution);
         play=0;
      elseif solution==-1,
         play=0;
         text=sprintf('Solution does not exist.\n');
      end %

      % appear text
       set(h.console,'String',text );

      %  store new solution
      h.line.t = t;
      h.line.alpha = alpha;
      h.line.fi = fi;
      set(hfigure,'UserData',h);
   end

   % enable these buttons
   set([h.btinfo h.btstep h.btclose h.btplay h.btreset h.pualgo ...
      h.editer h.btload h.btcreat],...
      'Enable','on');

   % disable stop button
   set(h.btstop,'Enable','off');


case 'step'
   % == Perform one adaptation step ================================================

   h=get(hfigure,'UserData');                           % get handlers we will need...

   % get sets
   sets=get(h.axes1,'UserData');

   % no data set loaded
   if isempty(sets)==1,
      return;
   end

   % get parameters
   t=h.line.t;
   alpha=h.line.alpha;
   fi=h.line.fi;
   X=qtransf(sets.X);

   % get # of iter.
   iter=max(1,round(str2num(get(h.editer,'String'))));
   % get epsilon
   epsil=str2num(get(h.edeps,'String'));

   % perfor one adaptation step
   switch get(h.pualgo,'Value')
   case 1
      [alpha,fi,solution,tplus1]=perceptr(X,sets.I,iter,t,alpha,fi);
   case 2
      [alpha,fi,solution,tplus1]=kozinec(X,sets.I,iter,t,alpha,fi);
   case 3
      [alpha,fi,solution,tplus1]=ekozinec(X,sets.I,epsil,iter,t,alpha,fi);
   case 4
      [alpha,fi,solution]=linsvm(X,sets.I);
      if solution==0, solution=-1; end
      tplus1=1;
   end

   t=tplus1;
   if get(h.xbanim,'Value')==0,
      quademo('drawline',hfigure,fi,alpha);
   else
      quademo('animline',hfigure,fi,alpha);
   end

   if solution==0 | solution==1,
      % appear time and line parameters
      text=makeinfo(t,alpha,fi,solution);
   elseif solution==-1,
      text=sprintf('Solution does not exist.\n');
   end %
   set(h.console,'String',text );

   %  store new solution
   h.line.t = t;
   h.line.alpha = alpha;
   h.line.fi = fi;
   set(hfigure,'UserData',h);


case 'animline'
   % == Perform smooth transition of line from old to new position ==========

   h=get(hfigure,'UserData');                     % get handlers

   % old position of line is...
   alpha2=h.line.alpha;
   fi2=h.line.fi;
   t2=h.line.t;

   % New position get from input arguments
   fi1=varargin{1};
    alpha1=varargin{2};

   if t2~=0,
      % move line
    step=1/ANIM_STEPS;
       for k=0:step:1,
       alpha=(1-k)*alpha2+k*alpha1;         % smooth transition of alpha
        fi=(1-k)*fi2+k*fi1;                     % --//--                        fi

          quademo('drawline',hfigure,fi,alpha);
      end
   else
      % it is first step
      quademo('drawline',hfigure,fi1,alpha1);               % first step
   end % if t2~=0


case 'reset'
   % == Reset adaptation process, set up zero step ================

   h=get(hfigure,'UserData');                     % get handlers

   % get data set
   sets=get(h.axes1,'UserData');

   % get file
   file=get(h.btload,'UserData');

   % zeroize parameters of the separation line
   h.line.t=0;
   h.line.fi=0;
   h.line.alpha=[0;0;0;0;0];

   if h.line.handler1==-1,
      h.line.handler1=plot([0],[0],'LineWidth',LINE_WIDTH,'EraseMode','xor','Color','k');
      h.line.handler2=plot([0],[0],'LineWidth',LINE_WIDTH,'EraseMode','xor','Color','k');
   else
      set(h.line.handler1,'Visible','off');
      set(h.line.handler2,'Visible','off');
   end % if hline~=-1

   % set up handlers and flush queue with graph. objects
   set(hfigure,'UserData',h);

   % creat comment
   if isempty(sets)==0,
      consoletext=sprintf('Step t=0\nNo separation line');
      titletext=sprintf('File: %s, # of points K = %d',file.name,sum(sets.K));
   else
      consoletext=sprintf('No data loaded.\nPress Load data button.\n');
      titletext='';

      pos=get(h.axes1,'Position');
      fsize=min(pos(3),pos(4))/10;
      setaxis(h.axes1,[-1 1 -1 1]);
%%%      axis([-1 1 -1 1]);
      builtin('text',0,0,'Press ''Load data'' button.',...
         'HorizontalAlignment','center',...
         'FontUnits','normalized',...
         'Clipping','on',...
         'FontSize',fsize);
   end

   % show comment
   set(h.console,'String',consoletext );

   % print title
   pos=get(h.axes1,'Position');
   fsize=(1-pos(2)-pos(4))*1;
   title(titletext,...
      'VerticalAlignment','bottom',...
      'HorizontalAlignment','left',...
      'FontUnits','normalized',...
      'Units','normalized',...
      'Position',[0 1 0],...
      'FontSize',fsize);


case 'drawline'
   % == Draw separation line ==================================================

   h=get(hfigure,'UserData');              % get handlers

   % get new line position from input arguments
   fi=varargin{1};
   alpha=varargin{2};

   [A,B,C]=l2q2d(alpha,fi);
%%%   win=axis;
   [X1,Y1,X2,Y2]=quad2d(A,B,C,getaxis(h.axes1));

   % hide old curvatures
   set(h.line.handler1,'Visible','off');
   set(h.line.handler2,'Visible','off');

   % appear new ones
   set(h.line.handler1,'XData',X1,'YData',Y1,'Visible','on');
   set(h.line.handler2,'XData',X2,'YData',Y2,'Visible','on');

   % store data
   set(hfigure,'UserData',h);

   % flush draw queue
   drawnow;


case 'info'
   % == Call standard Matlab`s info box =========================================
   helpwin(mfilename);


end

%========================================
function [text]=makeinfo(t,alpha,fi,solution)

[A,B,C]=l2q2d(alpha,fi);

if solution==1,
   txline{1}=sprintf('Solution was found after t=%d step(s).',t);
else
   txline{1}=sprintf('Step t=%d',t);
end
txline{2}=sprintf('Quadratic function:');
txline{3}=sprintf('%f x^2 + %f x + %f xy + %f y + %f y^2 + %f = 0',...
   A(1,1),B(1),A(1,2)+A(2,1),B(2),A(2,2),C);

text='';
for i=1:3,
   text=strvcat(text,txline{i});
end

return